package io.yyxx.boot.util.map;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import org.apache.commons.codec.binary.Base64;

public class CryptUtilPublic {

  /**
   * 密钥长度: 128, 192 or 256，默认128，不要随意改
   */
  private static final int KEY_SIZE = 128;

  private static final Base64 base64 = new Base64();

  /**
   * 加密/解密算法名称
   */
  private static final String ALGORITHM = "AES"; // AES = AES/ECB/PKCS5Padding

  /**
   * 随机数生成器（RNG）算法名称
   */
  private static final String RNG_ALGORITHM = "SHA1PRNG";


  /**
   * 生成密钥对象
   */
  private static SecretKey generateKey(String key) throws Exception {

    // 创建安全随机数生成器
    SecureRandom random = SecureRandom.getInstance(RNG_ALGORITHM);
    // 设置 密钥key的字节数组 作为安全随机数生成器的种子
    random.setSeed(key.getBytes());
    // 创建 AES算法生成器
    KeyGenerator gen = KeyGenerator.getInstance(ALGORITHM);
    // 初始化算法生成器
    gen.init(KEY_SIZE, random);
    return gen.generateKey();
  }

  /**
   * @param originalData 原始文本
   * @param key
   * @return
   * @throws Exception
   */

  public static String encrypt(String originalData, String key) throws Exception {
    byte[] plainBytes = originalData.getBytes(StandardCharsets.UTF_8);
    if (plainBytes.length == 0) {
      return "";
    }
    if (key == null || key.length() == 0) {
      return "";
    }

    SecretKey secKey = generateKey(key);
    Cipher cipher = Cipher.getInstance(ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, secKey);
    byte[] cipherBytes = cipher.doFinal(plainBytes);

    return base64encode(cipherBytes);
  }

  protected static byte[] base64decode(String str) {
    return base64.decode(str);
  }

  protected static String base64encode(byte[] bytes) {
    return base64.encodeToString(bytes);
  }

  /**
   * 将二进制转换成16进制
   *
   * @param buf
   * @return
   */
  public static String parseByte2HexStr(byte buf[]) {

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < buf.length; i++) {
      String hex = Integer.toHexString(buf[i] & 0xFF);
      if (hex.length() == 1) {
        hex = '0' + hex;
      }
      sb.append(hex.toUpperCase());
    }
    return sb.toString();
  }

  /**
   * 将16进制转换为二进制
   *
   * @param hexStr
   * @return
   */
  public static byte[] parseHexStr2Byte(String hexStr) {
    if (hexStr.length() < 1) {
      return null;
    }
    byte[] result = new byte[hexStr.length() / 2];
    for (int i = 0; i < hexStr.length() / 2; i++) {
      int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
      int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
      result[i] = (byte) (high * 16 + low);
    }
    return result;
  }


  public static String decrypt(String encrypedData, String key) throws Exception {

    byte[] cipherBytes = base64decode(encrypedData);
    SecretKey secKey = generateKey(key);

    Cipher cipher = Cipher.getInstance(ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, secKey);

    byte[] plainBytes = cipher.doFinal(cipherBytes);
    return new String(plainBytes, StandardCharsets.UTF_8);
  }

  public static void main(String[] args) {
    try {
      String originalData = "14464614210中文的001";
      String key = "asdfasdasdfsdfasdf23434tgsdfhxcvau4IKf";
      String encrypedData = encrypt(originalData, key);

      String decryptedText = decrypt(encrypedData, key);
      System.out.println("original value: " + originalData);
      System.out.println("encrypted value: " + encrypedData);
      System.out.println("original value: " + decryptedText);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
